package com.lrj.websocket.socket;

import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/webSocket/{username}")
@Component
public class WebSocket {
    private static int onlineCount = 0;
    private static Map<String, WebSocket> clients = new ConcurrentHashMap();

    private String username;
    private Session session;

    /**
     * 添加@OnOpen注解的方法可以没有形参，形参列表的顺序任意，但不能出现形参列表外的形参
     */
    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) {
        this.username = username;
        this.session = session;

        clients.put(username, this);
        addOnlineCount();
        System.out.println("当前人数：" + onlineCount);
    }

    @OnClose
    public void onClose() {
        System.out.println(String.format("用户[%s]关闭连接", this.username));
        subOnlineCount();
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println(String.format("用户[%s]发送消息：%s", this.username, message));
        sendMessageAll(message);
    }


    /**
     * 添加@OnError注解的方法必须要有Throwable形参，否则注册失败
     * @param error
     */
    @OnError
    public void onError(Throwable error, Session session) {
        System.out.println(String.format("用户[%s]发生异常", this.username));
        System.out.println(session);
        System.out.println(error);
    }

    //发送给指定用户
    public void sendMessageTo(String message, String to) {
        for (WebSocket websocket : clients.values()) {
            if (websocket.username.equals(to)) {
                websocket.session.getAsyncRemote().sendText(message);
            }
        }
    }

    //发送给全部用户
    public void sendMessageAll(String message) {
        for (WebSocket websocket : clients.values()) {
            websocket.session.getAsyncRemote().sendText(message);
        }
    }

    //新用户加入（加锁）
    public static synchronized void addOnlineCount() {
        WebSocket.onlineCount ++;
    }

    //用户关闭连接（加锁）
    public static synchronized void subOnlineCount() {
        WebSocket.onlineCount --;
    }
}